package ua.org.enginer.managers
{
	import com.google.analytics.AnalyticsTracker;
	import com.google.analytics.GATracker;
	import com.google.analytics.debug.VisualDebugMode;
	
	import flash.display.DisplayObject;
	import flash.events.Event;
	import flash.utils.getQualifiedClassName;
	
	import mx.core.Container;
	import mx.core.UIComponent;
	import mx.managers.SystemManager;
	
	import ua.org.enginer.tracking.ButtonTrackingImpl;
	import ua.org.enginer.tracking.ComboBoxTrackingImpl;
	import ua.org.enginer.tracking.ContainerTrackingImpl;
	import ua.org.enginer.tracking.ITrackingObject;
	import ua.org.enginer.tracking.ListTrackingImpl;
	import ua.org.enginer.tracking.UIComponentTrackingImpl;
	import ua.org.enginer.tracking.ViewStackTrackingImpl;
	import ua.org.enginer.utils.ClassUtils;
		
	public class GATrackingManager {
		
		private var account:String
		private var tracker:AnalyticsTracker
		
		function GATrackingManager(account:String) {
			this.account = account
		}
		
		public function init(obj:Object):void {
			// listen for popUps and etc.
			SystemManager.getSWFRoot(obj).addEventListener(Event.ADDED, onAdded)
			
			tracker = new GATracker(SystemManager.getSWFRoot(obj), account, "AS3", true);
			tracker.debug.verbose = true;
            tracker.debug.mode = VisualDebugMode.advanced;
            tracker.debug.traceOutput = true;
            //tracker.debug.GIFRequests = true;
		}
		
		public function accociateComponent(component:UIComponent):void {
			if (!component) return;
			
			var implementationClass:Class = findTrackingImplementation(component);
			if (implementationClass) {
	    		var implementation:ITrackingObject = new implementationClass(component);
	    		implementation.tracker = tracker
	    		implementationInstances.push(implementation);
	  		} else {
	    		trace("***no implementation:"+component+"=>"+getQualifiedClassName(component)+" <<"+implementationClass);				    	
	    	}
		}
		
		private function findTrackingImplementation(component:UIComponent):Class {
			var componentName:String = getQualifiedClassName(component);

			var componentClassName:String = componentName.split("::")[1]+"TrackingImpl";
			var clazz:Class = findTrackingImplementationClassByName(componentClassName);
			if (clazz) return clazz; // found tracking implementation
			
			// That's it, let's not go higher in the chain.
			if ("mx.core::UIComponent" == componentClassName) return null; 
			
			
			trace("\t search parent:"+component.className);
			for each (componentName in ClassUtils.inheritance(component)) {
				trace("\t\t :"+componentName);
				componentClassName = componentName.split("::")[1]+"TrackingImpl";
				clazz = findTrackingImplementationClassByName(componentClassName);
				if (clazz) return clazz; // found tracking implementation				
			}
			// not found
			return null;			
		}
		
		private function findTrackingImplementationClassByName(componentClassName:String):Class {
			for each (var item:Class in implementationClasses) {
				var implementationClassName:String = getQualifiedClassName(item);
				if (implementationClassName.indexOf("::"+componentClassName) > 0) return item;
			}
			return null;
		}
		
		private function onAdded(event:Event):void {
			if (event.target is UIComponent) {
				accociateComponent(UIComponent(event.target))
				if (event.target is Container) {
					for each(var child:DisplayObject in Container(event.target).getChildren())
						if (child is UIComponent) accociateComponent(UIComponent(child))
				}
					
			}
		}
		
		private var implementationInstances:Array = [];
		
		private var implementationClasses:Array = [
			UIComponentTrackingImpl,
			ButtonTrackingImpl,
			ContainerTrackingImpl,
			ViewStackTrackingImpl,
			ComboBoxTrackingImpl,
			ListTrackingImpl
		]
	}
}